﻿#include "remoteobjectnode.h"
#include "remoteobjecthost.h"
#include "remoteobject_p.h"
#include "metafunction.h"
#include "metaproperty.h"
#include "metasignal.h"
#include "remoteobject.h"

BeginMetaData(RemoteObject)

META_DefaultConstructor

META_BEGIN_SIGNAL(Initialized)META_END_PROPERTY



EndMetaData

struct RemoteObject::Private{
    Private(){
        node = NULL;
        role = R_Independent;
        status = S_None;
        SignatureId = 0;
    }

    RemoteObjectNodeBase* node;
    Role role;
    Status status;
    unsigned long long SignatureId;
};


void RemoteObject::PrivateInit(RemoteObject::PrivateCreate &p)
{
    _P->node = p.node;
    _P->role = p.role;
    _P->status = p.status;
}

RemoteObject::RemoteObject():_P(new Private())
{

}

RemoteObject::~RemoteObject()
{
    if(_P->node){
        _P->node->UnRegister(this);
    }
}

RemoteObject::Role RemoteObject::GetRole() const
{
    return _P->role;
}

RemoteObject::Status RemoteObject::GetStatus() const
{
    return _P->status;
}

void RemoteObject::__RMTSetValue(int idx, Variant value)
{
    if(_P->role == RemoteObject::R_Replica){
        //这是副本，将设置属性转换为请求
        RemoteObjectNode* node = dynamic_cast<RemoteObjectNode*>(_P->node);
        node->pushProperty(this,idx,value);
    }
    else{
        //这是原件，直接设置

		UpdateValue(idx, value);
	}
}

Variant RemoteObject::__RMTGetValue(int idx) const
{
	auto property = GetMetaInfo().GetProperty(idx);

	auto impName = "Get" + property.Name() + "Imp";
	auto impSignature = ReflectUtils::GetSignature(impName, {});
	Variant ret;
	GetMetaInfo().GetFunction(GetMetaInfo().IndexOfFunction(impSignature.c_str())).DynamicInvoke((void*)dynamic_cast<const void*>(this), ret, {});

    return ret;
}

RemoteObjectNodeBase *RemoteObject::GetNode()
{
    return _P->node;
}

void RemoteObject::UpdateValue(int idx, Variant value)
{
	auto property = GetMetaInfo().GetProperty(idx);

	auto impName = "Set" + property.Name() + "Imp";
	auto impSignature = ReflectUtils::GetSignature(impName, { property.Type() });
	Variant v;
	GetMetaInfo().GetFunction(GetMetaInfo().IndexOfFunction(impSignature.c_str())).DynamicInvoke(dynamic_cast<void*>(this), v, {value});
}

unsigned long long RemoteObject::GetTypeSignature()
{
	if (_P->SignatureId == 0) {
		
		_P->SignatureId = DoGetTypeSignature();
	}

	return 0;
}

unsigned long long RemoteObject::DoGetTypeSignature()
{
	return  GetSignature(ExtractMetaInfo(GetMetaInfo()));
}

std::shared_ptr<WorkFuture<Variant>> RemoteObject::Invoke(int index,const void **param,bool Sync)
{
    MetaFunction fun = GetMetaInfo().GetFunction(index);

    if(_P->role == RemoteObject::R_Replica){
        //此为副本，使函数在远端执行
        auto node = dynamic_cast<RemoteObjectNode*>(_P->node);

        auto types = fun.GetParamTypes();
        VariantList p;
        for(int i = 0;i<types.size();i++){
            p.push_back(Variant(param[i],types[i]));
        }

        return node->invokeFunction(this,index,p,Sync);
    }
    else{
        //此为原件，直接执行函数实现
        std::shared_ptr<WorkFuture<Variant>> ret = std::make_shared<WorkFuture<Variant>>();
        std::string impName = fun.GetName() + "Imp";
        std::string signature = ReflectUtils::GetSignature(impName,fun.GetParamTypes());

		auto impFun = GetMetaInfo().GetFunction(GetMetaInfo().IndexOfFunction(signature.c_str()));

		auto returnType = impFun.GetReturnType();

		Variant retval;
		void* r = Variant::BeReadyForReturn(retval,returnType);

		ret->AddWork();
		impFun.UnSafeInvoke(dynamic_cast<void*>(this), r,param);

		ret->FinishWork(retval);

        return ret;
    }

    return NULL;
}

void RemoteObject::SetStatus(Status status)
{
    _P->status = status;
}

void RemoteObject::SetRole(Role role)
{
    _P->role = role;
}